package com.moli.iov.handle.alarm.service.impl;

import static org.springframework.data.mongodb.core.query.Criteria.where;

import com.moli.iov.handle.alarm.enums.AlarmStatusEnum;
import com.moli.iov.handle.alarm.model.dto.AlarmInfoDto;
import com.moli.iov.handle.alarm.model.po.AlarmInfo;
import com.moli.iov.handle.alarm.service.IAlarmInfoService;
import com.moli.iov.util.StringUtil;
import java.util.Arrays;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

/**
 * <p>
 *
 * </p>
 *
 * @author: zql
 * @Date: 2019/2/13 10:38
 */
@Slf4j
@Service("alarmService")
public class AlarmInfoServiceImpl implements IAlarmInfoService {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 添加报警
     * @param alarmInfo
     * @return
     */
    @Override
    public void save(AlarmInfo alarmInfo) {
        mongoTemplate.save(alarmInfo);
    }

    /**
     * 取消报警
     * @param alarmInfo
     */
    @Override
    public void updateAlarm(AlarmInfo alarmInfo) {

        String statusKey = "status";
        List<Integer>statuses = Arrays.asList(AlarmStatusEnum.ALARMING.getFlag(),
                                AlarmStatusEnum.IGNORE.getFlag());

        Query query = Query.query(where("vin").is(alarmInfo.getVin())
                            .and("alarmCode").is(alarmInfo.getAlarmCode())
                            .and(statusKey).in(statuses));

        Update update = Update.update("endTime", alarmInfo.getEndTime())
                        .set(statusKey, AlarmStatusEnum.ALARM_END.getFlag())
                        .set("duration", alarmInfo.getDuration())
                        .set("durationStr", alarmInfo.getDurationStr());

        if(alarmInfo.getDisarmLocation() != null){
            update.set("disarmLocation", alarmInfo.getDisarmLocation());
        }

        mongoTemplate.updateFirst(query, update, AlarmInfo.class);
    }

    /**
     * 忽略中更新为报警中
     * @param alarmInfo
     */
    @Override
    public void updateAlarmOfIgnore(AlarmInfo alarmInfo) {
        String statusKey = "status";
        Query query = Query.query(where("vin").is(alarmInfo.getVin())
            .and("alarmCode").is(alarmInfo.getAlarmCode())
            .and(statusKey).in(AlarmStatusEnum.IGNORE.getFlag()));

        Update update = Update.update(statusKey, alarmInfo.getStatus());
        mongoTemplate.updateFirst(query, update, AlarmInfo.class);
    }

    /**
     * 查询报警列表
     * @return
     */
    @Override
    public List<AlarmInfo> listAlarmInfo(AlarmInfo alarmInfo) {
        return mongoTemplate.find(createQuery(alarmInfo), AlarmInfo.class);
    }

    /**
     * 生成查询条件
     * @param alarmInfo
     * @return
     */
    private Query createQuery(AlarmInfo alarmInfo){

        Query condition= new Query();

        if(StringUtil.isNotBlank(alarmInfo.getVin())){
            condition.addCriteria(Criteria.where("vin").is(alarmInfo.getVin()));
        }

        if(alarmInfo.getAlarmCode() != null){
            condition.addCriteria(Criteria.where("alarmCode").is(alarmInfo.getAlarmCode()));
        }

        if(alarmInfo.getStatus() != null){
            condition.addCriteria(Criteria.where("status").is(alarmInfo.getStatus()));
        }

        return condition;
    }

    /**
     * 查询报警列表
     * @param alarmInfoDto
     * @return
     */
    @Override
    public List<AlarmInfo> listAlarmInfo(AlarmInfoDto alarmInfoDto) {
        return mongoTemplate.find(createQuery(alarmInfoDto), AlarmInfo.class);
    }

    /**
     * 生成查询条件
     * @param alarmInfoDto
     * @return
     */
    private Query createQuery(AlarmInfoDto alarmInfoDto){

        Query condition= new Query();
        if(alarmInfoDto == null){
         return condition;
        }

        if(alarmInfoDto.getAlarmCode() != null){
            condition.addCriteria(Criteria.where("alarmCode").is(alarmInfoDto.getAlarmCode()));
        }

        if(alarmInfoDto.getStatus() != null){
            condition.addCriteria(Criteria.where("status").is(alarmInfoDto.getStatus()));
        }

        if(alarmInfoDto.getStatues() != null && !alarmInfoDto.getStatues().isEmpty()){
            condition.addCriteria(Criteria.where("status").in(alarmInfoDto.getStatues()));
        }

        return condition;
    }
}
